using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using ProtoGame.GameLib.Entities;
using System.Text;
using ProtoGame.Input;


namespace ProtoGame.GameLib.GameComponents
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class DialogBox<TEnum> : TextBox<TEnum> where TEnum : struct
    {

        private DialogBox(string fontPath, Game game)
            : base(fontPath, game)
        {
            TextBoundingBox = null;
        }

        public GraphicEntity TextBoundingBox { get; set; }

        protected override void PlaceWidgets()
        {
            Vector2 dialogDimension = Vector2.Zero;

            if (Illustration == null)
            {
                TextSprite.Position = Position + WidgetsOffset;
                dialogDimension = Dimension - 2 * WidgetsOffset;
            }
            else
            {
                Illustration.Position = Position + WidgetsOffset;

                int portraitRight = Illustration.Bounds.Right;
                TextSprite.Position = new Vector2(
                    portraitRight + WidgetsOffset.X,
                    Position.Y + WidgetsOffset.Y);

                dialogDimension.X = Dimension.X - Illustration.Bounds.Width - 2 * WidgetsOffset.X;
                dialogDimension.Y = Dimension.Y - 2 * WidgetsOffset.Y;
            }
            TextSprite.FitText(Text, dialogDimension.X, dialogDimension.Y);

            CalculateTextBoxScale();

            base.PlaceWidgets();
        }

        void CalculateTextBoxScale()
        {
            if (TextBoundingBox != null)
            {
                TextBoundingBox.Position = Position;

                TextBoundingBox.Scale = new Vector2(1f);
                Rectangle bounds = TextBoundingBox.Bounds;
                Vector2 boxDims = new Vector2(bounds.Width, bounds.Height);
                TextBoundingBox.Scale = Dimension / boxDims;
            }
        }

        public void AddSpeech(GraphicEntity portrait, string text)
        {
            AddFrame(portrait, text);
        }

        public void AddSpeech(string text)
        {
            AddSpeech(null, text);
        }

        #region Override Members
        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        protected override void LoadContent()
        {
            base.LoadContent();
        }

        protected override void ApplyFade()
        {
            if (TextBoundingBox != null)
                TextBoundingBox.Fade = ScreenState.Fade;

            base.ApplyFade();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            if (TextBoundingBox != null)
                TextBoundingBox.Update(gameTime);

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);

            if (TextBoundingBox != null)
                TextBoundingBox.Draw(SpriteBatch);

            base.Draw(gameTime);

            SpriteBatch.End();
        }
        #endregion

        public static DialogBox<TEnum> CreateBottomDialogBox(GraphicEntity boxGfx, string fontPath, Game game)
        {
            Vector2 viewportDims = new Vector2(game.GraphicsDevice.Viewport.Width, game.GraphicsDevice.Viewport.Height);

            Rectangle bounds = Rectangle.Empty;
            bounds.X = (int)(viewportDims.X * 0.05f);
            bounds.Y = (int)(viewportDims.Y * 0.75f);
            bounds.Width = (int)(viewportDims.X * 0.95f) - bounds.X;
            bounds.Height = (int)(viewportDims.Y * 0.95f) - bounds.Y;

            DialogBox<TEnum> box = new DialogBox<TEnum>(fontPath, game);
            box.Initialize();
            box.TextBoundingBox = boxGfx;
            box.Position = new Vector2(bounds.X, bounds.Y);
            box.Dimension = new Vector2(bounds.Width, bounds.Height);
            box.WidgetsOffset = new Vector2(bounds.Width * 0.025f, bounds.Height * 0.10f);

            ScreenStateEffects sse = new ScreenStateEffects();
            sse.StartingTime = TimeSpan.Zero;
            sse.EndingTime = TimeSpan.Zero;
            box.ScreenState = sse;

            return box;
        }
    }
}